import threading
import subprocess
import os
import tkinter as tk
from tkinter import filedialog, scrolledtext

from PIL import ImageTk

from book.content import ContentType
from model.glm_model import GLMModel
from model.openai_model import OpenAIModel
from translator.pdf_translator import PDFTranslator
from utils.config_loader import ConfigLoader
from utils.logger import LOG

class UserInterface:
    def __init__(self):
        self.file_button = None
        self.result_label = None
        self.language_var = None
        self.file_path = None
        self.result_path = None
        self.file_selected_label = None
        self.model_var = None
        self.text_area = None
        self.page_number = None
        self.window = tk.Tk()
        self.window.minsize(800, 360)
        self.window.title("PDF Translator")
        self.create_widgets()

    def create_widgets(self):
        row_index = 0
        # 创建模型选择部分
        model_label = tk.Label(self.window, text="选择模型:")
        model_label.grid(row=row_index, column=0, sticky="w", padx=16, pady=8)

        self.model_var = tk.StringVar()
        self.model_var.set("OpenAIModel")

        model_option_menu = tk.OptionMenu(self.window, self.model_var, "OpenAIModel", "GLMModel")
        model_option_menu.grid(row=row_index, column=1, sticky="w")

        row_index += 1

        # 创建文件选择部分
        file_label = tk.Label(self.window, text="选择文件:")
        file_label.grid(row=row_index, column=0, sticky="w", padx=16, pady=8)

        self.file_button = tk.Button(self.window, text="选择文件", command=self.select_file)
        self.file_button.grid(row=row_index, column=1, sticky="w")

        row_index += 1

        # 创建模型选择语言部分
        translator_language_label = tk.Label(self.window, text="选择翻译语言:")
        translator_language_label.grid(row=row_index, column=0, sticky="w", padx=16, pady=8)

        self.language_var = tk.StringVar()
        self.language_var.set("中文")

        language_option_menu = tk.OptionMenu(self.window, self.language_var, "中文", "英文",
                                             "日语", "俄语", "韩语", "阿拉伯语", "西班牙语", "葡萄牙语")
        language_option_menu.grid(row=row_index, column=1, sticky="w")

        row_index += 1

        # 翻译页数
        page_label = tk.Label(self.window, text="翻译页数(默认翻译全部):")
        page_label.grid(row=row_index, column=0, sticky="w", padx=16, pady=8)

        page_entry = tk.Entry(self.window, textvariable=self.page_number, width=5)
        page_entry.grid(row=row_index, column=1, sticky="w")

        row_index += 1

        # 选中的文件部分
        self.file_selected_label = tk.Label(self.window, text="选择的文件是:未选择")
        self.file_selected_label.grid(row=row_index, column=0, sticky="w", padx=16, pady=8)

        translator_button = tk.Button(self.window, text="开始翻译", command=self.translate_file)
        translator_button.grid(row=row_index, column=1, sticky="w")

        row_index += 1

        # 翻译结果路径
        self.result_label = tk.Label(self.window, text="翻译结果:")
        self.result_label.grid(row=row_index, column=0, sticky="w", padx=16, pady=8)

        result_open_button = tk.Button(self.window, text="打开", command=self.open_translator_result)
        result_open_button.grid(row=row_index, column=1, sticky="w")

        row_index += 1

        # 内容预览
        text_label = tk.Label(self.window, text="内容预览:")
        text_label.grid(row=row_index, column=0, sticky="w", padx=16)

        row_index += 1

        self.text_area = scrolledtext.ScrolledText(self.window, wrap=tk.WORD)
        self.text_area.grid(row=row_index, column=0, columnspan=3, padx=16, pady=8, sticky="nsew")

        # 设置Grid布局的行和列的权重，使得文本区域可以随窗口大小变化而变化
        self.window.grid_rowconfigure(row_index, weight=1)
        self.window.grid_columnconfigure(0, weight=1)

    def select_model(self):
        selected_model = self.model_var.get()
        # 在这里执行选择模型的逻辑
        LOG.info("选择的模型是:", selected_model)

    def select_file(self):
        self.file_path = filedialog.askopenfilename(filetypes=[("PDF Files", "*.pdf")])
        # 在这里执行选择文件的逻辑
        LOG.info("选择的文件路径是:", self.file_path)
        self.file_selected_label.config(text="选择的文件是:" + self.file_path)

    def translate_file(self):
        if self.file_path is None:
            tk.messagebox.showinfo("提示", "需要先选择PDF文件，才能开始翻译")
        else:
            LOG.debug("开始翻译")
            self.result_label.config(text="翻译中，请耐心等待...", fg="blue")
            # 创建子线程
            translation_thread = threading.Thread(target=self.translate_file_in_thread,
                                                  args=(self.on_translation_complete, "book"))
            # 启动子线程
            translation_thread.start()

    def translate_file_in_thread(self, callback, book):
        try:
            pdf_file_path = self.file_path
            file_format = "PDF"
            target_language = self.language_var.get()

            config_loader = ConfigLoader("./config.yaml")
            config = config_loader.load_config()

            selected_model = self.model_var.get()
            if selected_model == "OpenAIModel":
                model_name = config['OpenAIModel']['model']
                api_key = config['OpenAIModel']['api_key']
                model = OpenAIModel(model=model_name, api_key=api_key)
                translator = PDFTranslator(model)
            else:
                model_url = config['GLMModel']['model_url']
                model = GLMModel(model_url=model_url)
                translator = PDFTranslator(model)
            if self.page_number:
                page_number = self.page_number.get()
                translator.translate_pdf(pdf_file_path, file_format, target_language, pages=int(page_number))
            else:
                translator.translate_pdf(pdf_file_path, file_format, target_language)
            # 回调给主线程展示结果
            callback(translator.book)
            LOG.debug("翻译结束")

        except Exception as e:
            # 处理异常
            LOG.error("翻译过程中出现错误:", str(e))
            self.result_label.config(text="翻译结果:" + str(e), fg="red")

    def on_translation_complete(self, book):
        # 更新翻译结果路径，直接默认在pdf的同级目录生成
        output_file_path = book.pdf_file_path.replace('.pdf', f'_translated.pdf')
        self.result_path = output_file_path;
        self.result_label.config(text="翻译结果:" + self.result_path, fg="green")
        self.text_area.delete('1.0', tk.END)
        # 更新内容到预览
        for page in book.pages:
            for content in page.contents:
                if content.status:
                    if content.content_type == ContentType.TEXT:
                        # str
                        text = content.translation
                        self.text_area.insert(tk.END, text + "\n")
                    elif content.content_type == ContentType.TABLE:
                        # list
                        table = content.translation
                        header = '| ' + ' | '.join(str(column) for column in table.columns) + ' |' + '\n'
                        separator = '| ' + ' | '.join(['---'] * len(table.columns)) + ' |' + '\n'
                        # body = '\n'.join(['| ' + ' | '.join(row) + ' |' for row in table.values.tolist()]) + '\n\n'
                        body = '\n'.join(['| ' + ' | '.join(str(cell) for cell in row) + ' |' for row in
                                      table.values.tolist()]) + '\n\n'
                        self.text_area.insert(tk.END, header + separator + body)
                    elif content.content_type == ContentType.IMAGE:
                        #  PILImage.Image
                        image = content.translation
                        # 将Image对象转换为PhotoImage对象
                        photo = ImageTk.PhotoImage(image)
                        # 在ScrolledText中插入图片
                        self.text_area.image_create(tk.END, image=photo)

    def open_folder(self, file_path):
        folder_path = os.path.dirname(file_path)
        # 根据操作系统的不同，使用不同的命令打开文件夹
        if os.name == 'nt':  # Windows系统
            subprocess.run(['explorer', folder_path])
        elif os.name == 'posix':  # macOS或Linux系统
            subprocess.run(['open', folder_path])
        else:
            LOG.error("Unsupported operating system.")

    def open_translator_result(self):
        if self.result_path is None:
            tk.messagebox.showinfo("提示", "目前没有翻译结果，请在翻译完成后再尝试")
        else:
            self.open_folder(self.result_path)

    def run(self):
        # 运行主循环
        self.window.mainloop()
